package com.telit.common.vo;

import lombok.Data;


/**
 * 接口统一返回对象VO
 *
 * @author Tracine
 * @since 2021-05-10
 */
@Data
public class ResultVo<TSource> {

    private int code;
    private String desc;
    private TSource data;

    public static ResultVo ok() {
        return ok("成功");
    }

    public static ResultVo ok(Object o) {
        return new ResultVo(Template.SUCCESS, o);
    }

    public static ResultVo ok(String message, Object o) {
        return new ResultVo(Template.SUCCESS,message, o);
    }

    public static ResultVo failure() {
        return failure(Template.EXCEPTION, "");
    }

    public static ResultVo failure(int code, String msg) {
        return new ResultVo(code,msg);
    }

    public static ResultVo failure(Template code) {
        return failure(code, "");
    }

    public static ResultVo failure(Template code, Object o) {
        return new ResultVo(code, o);
    }

    public ResultVo() {
        // jackson 要求对象拥有无参构造方法
    }

    public ResultVo(Template template) {
        this.code = template.getCode();
        this.desc = template.getDesc();
    }

    public ResultVo<TSource> desc(String desc) {
        this.desc = desc;
        return this;
    }

    public ResultVo<TSource> data(TSource data) {
        this.data = data;
        return this;
    }

    public enum Template {
        /** 操作成功 */
        SUCCESS(20000, "操作成功"),
        AUTHC_ILLEGAL(40101, "登录凭据无效"),
        AUTHC_FAILURE(40102, "系统认证失败"),
        AUTHC_LOCKED(40103, "用户账户已被锁定"),
        AUTHC_FORBID(40104, "用户账户已被禁用"),
        AUTHZ_UNAUTHZ(40201, "访问资源未经授权"),
        FAILURE(50000, "操作失败"),
        ARG_PARSE_GET(50011, "GET请求参数解析失败"),
        ARG_PARSE_POST(50012, "POST请求参数解析失败"),
        ARG_BIND_GET(50013, "GET请求参数校验失败"),
        ARG_BIND_POST(50014, "POST请求参数校验失败"),
        NOT_ALLOWED_METHOD(50015, "不支持当前请求方法"),
        NOT_ALLOWED_MEDIA(50016, "不支持当前媒体类型"),
        EXCEPTION(59000, "服务器操作异常");

        Template(int code, String desc) {
            this.code = code;
            this.desc = desc;
        }

        private final int code;
        private final String desc;

        public int getCode() {
            return this.code;
        }

        public String getDesc() {
            return this.desc;
        }

    }

    public ResultVo(Template template, TSource data) {
        setResultCode(template);
        this.data = data;
    }

    public void setResultCode(Template template) {
        this.code = template.getCode();
        this.desc = template.getDesc();
    }

    public ResultVo(Template template, String desc, TSource data) {
        setResultCode(template);
        this.desc = desc;
        this.data = data;
    }

    public ResultVo(int code, String msg){
        this.code = code;
        this.desc = msg;
    }

}
